﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Media;

namespace GenTheme.Theme
{
    internal class Thread : IThread
    {
        private IThread top;
        private IThread bot;
        private Color? threadColor;
        private bool isVisible;

        private IThemeObject Owner;

        public Thread(Color? c, IThemeObject owner)
        {
            this.threadColor = c;
            this.Owner = owner;
        }

        private int GetLeftTopSteps(IThread t)
        { 
            // Get starting left path
            int steps = 0;
            if (this.Owner.LeftTop != null)
            {
                steps = this.Owner.LeftTop.BotThread.GetTopPath(t);
            }
            if (this.Owner.LeftTop != null && steps < 0)
            {
                steps = this.Owner.LeftTop.TopThread.GetTopPath(t);
            }

            return steps;
        }

        private int GetRightTopSteps(IThread t)
        { 
            // Get starting right path
            int steps = 0;
            if (this.Owner.RightTop != null)
            {
                steps = this.Owner.RightTop.BotThread.GetTopPath(t);
            }
            if (this.Owner.RightTop != null && steps < 0)
            {
                steps = this.Owner.RightTop.TopThread.GetTopPath(t);
            }

            return steps;
        }

        public int GetTopPath(IThread t)
        {
            if (this.threadColor == t.ThreadColor && !this.Equals(t))
            {
                return 0;
            }

            int leftPath = this.GetLeftTopSteps(t);
            int rightPath = this.GetRightTopSteps(t);

            if (leftPath >= 0 && leftPath < rightPath)
            {
                if (this.Owner.LeftTop != null && !this.Owner.LeftTop.BotThread.ThreadColor.HasValue)
                {
                    this.top = this.Owner.LeftTop.BotThread;
                }
                if (this.Owner.LeftTop != null && !this.Owner.LeftTop.TopThread.ThreadColor.HasValue)
                {
                    this.top = this.Owner.LeftTop.TopThread;
                }
                return ++leftPath;
            }

            if (rightPath >= 0 && rightPath < leftPath)
            {
                if (this.Owner.RightTop != null && !this.Owner.RightTop.BotThread.ThreadColor.HasValue)
                {
                    this.top = this.Owner.RightTop.BotThread;
                }
                if (this.Owner.RightTop != null && !this.Owner.RightTop.TopThread.ThreadColor.HasValue)
                {
                    this.top = this.Owner.RightTop.TopThread;
                }
                return ++rightPath;
            }

            if (rightPath != 0 && leftPath != 0)
            {
                return -1;
            }

            if (this.threadColor.HasValue)
            {
                return -1;
            }

            return 0;
        }

        public int  GetBotPath(IThread t)
        {
            return 0;
        }

        #region IThread Members

        public IThemeObject ThemeObject
        {
            get
            {
                return this.Owner;
            }
        }

        public virtual void SetColor(Color? c)
        {
            this.threadColor = c;
            if (c != null)
            {
                this.GetTopPath(this);
            }
        }

        #endregion

        #region Explicit IThread Members

        IThread IThread.Top
        {
            get
            {
                return this.top;
            }
        }

        IThread IThread.Bot
        {
            get
            { 
                return this.bot;
            }
        }

        Color? IThread.ThreadColor
        {
            get 
            {
                return this.threadColor;
            }
        }

        bool IThread.IsVisible
        {
            get
            {
                return this.Owner.TopThread.Equals(this);
            }
            set
            {
                if (value != ((IThread)this).IsVisible)
                {
                    this.Owner.SwapThreads();
                }
            }
        }

        #endregion
    }
}
